Skip to content

feat: default yarn nodeLinker to pnpm#1852

Closed
fengmk2 wants to merge 1 commit into
mainfrom
feat/yarn-nodelinker-pnpm
Closed

feat: default yarn nodeLinker to pnpm#1852
fengmk2 wants to merge 1 commit into
mainfrom
feat/yarn-nodelinker-pnpm

Conversation

@fengmk2

@fengmk2 fengmk2 commented Jun 16, 2026

Copy link
Copy Markdown
Member

What

Change the default yarn linker written by vp create and vp migrate from node-modules to pnpm.

Why

The pnpm linker keeps real on-disk node_modules entries (backed by a content-addressable store), so it avoids Plug'n'Play's zip entries that break @oxlint/migrate's fileURLToPath resolution, while giving strict resolution and disk savings.

Notes

  • nodeLinker is only set when absent, so projects that already pin a linker keep their value.
  • Migrating a yarn project without an explicit linker now switches it to pnpm's strict resolution (undeclared transitive deps may surface as Cannot find module).

Change the default yarn linker written by vp create and vp migrate
from node-modules to pnpm (real on-disk node_modules via a
content-addressable store, unlike Plug'n'Play zip entries that break
@oxlint/migrate's fileURLToPath resolution).

nodeLinker is only set when absent, so projects that already pin a
linker keep their value. Migrating a yarn project without an explicit
linker now switches it to pnpm's strict resolution.
@fengmk2 fengmk2 self-assigned this Jun 16, 2026
@netlify

netlify Bot commented Jun 16, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit fb7397b
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a314b9facb31500089722cf

@fengmk2 fengmk2 added test: e2e Auto run e2e tests test: install-e2e run vite install e2e test test: create-e2e Run `vp create` e2e tests labels Jun 16, 2026
@fengmk2

fengmk2 commented Jun 16, 2026

Copy link
Copy Markdown
Member Author

Why it fails under yarn's nodeLinker: pnpm but not under pnpm

Core does a runtime import.meta.resolve('@typescript/native-preview') (a phantom dep it never declares). Both pnpm and yarn's pnpm linker use a store + symlinks, so why does this resolve under pnpm but break under yarn? One directory: pnpm has a global hoist dir inside the store; yarn's pnpm linker doesn't.

pnpm

node_modules/
  .pnpm/
    @voidzero-dev+vite-plus-core@x.y.z/
      node_modules/
        @voidzero-dev/vite-plus-core/   <- real files
        <core's declared deps>          -> symlinks
    @typescript+native-preview@a.b.c/
      node_modules/@typescript/native-preview/
    node_modules/                        <- catch-all hoist (hoist-pattern=['*'])
      @typescript/native-preview         -> symlink
      ...~every package in the graph...
  <project's direct deps>                -> symlinks into .pnpm

Resolving native-preview from core walks up to .pnpm/node_modules/ and finds it. pnpm is strict only at the project root; deeper in the store, any dep can reach almost any package (a deliberate compat compromise).

yarn nodeLinker: pnpm

node_modules/
  .store/
    @voidzero-dev-vite-plus-core-virtual-f02751107a/
      node_modules/
        @voidzero-dev/vite-plus-core/   <- real files
        <core's declared deps>          -> symlinks
    (no global .store/node_modules catch-all)
  <project's direct deps>               -> symlinks into .store

Same shape, but no catch-all. Each package sees only its declared (+ injected peer) deps, so the walk-up finds nothing and resolution fails.

Takeaway: yarn's nodeLinker: pnpm is actually stricter than pnpm, so it breaks phantom deps that real pnpm quietly hides, here vp pack. node-modules hid the problem via full hoisting.

Fix: declare @typescript/native-preview in @voidzero-dev/vite-plus-core (likely an optionalDependency); that's correct under every layout (yarn pnpm linker, PnP, pnpm). packageExtensions is a yarn-only band-aid.

@fengmk2 fengmk2 closed this Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test: create-e2e Run `vp create` e2e tests test: e2e Auto run e2e tests test: install-e2e run vite install e2e test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant